<template>
  <!-- 文章详情页 -->
  <Layout>
    <div ref="mainContainer" class="main-container" v-loading="isLoading">
      <BlogDetail v-if="data" :blog="data" />
      <!-- v-if是确保文章加载完成后才显示评论 -->
      <div id="comment-area" class="title" v-if="!isLoading">评论区</div>
      <BlogComment v-if="!isLoading" />
    </div>
    <template #right>
      <div class="right-container" v-loading="isLoading">
        <BlogTOC :toc="data.toc.length === 0 ? newToc : data.toc" v-if="data" />
      </div>
    </template>
  </Layout>
</template>

<script>
import fetchData from "@/mixins/fetchData";
import { getBlog } from "@/api/blog";
import Layout from "@/components/Layout";
import BlogDetail from "./components/BlogDetail";
import BlogTOC from "./components/BlogTOC";
import BlogComment from "./components/BlogComment";
import mainScroll from "@/mixins/mainScroll.js";
import { titleController } from "@/utils";

export default {
  mixins: [fetchData(null), mainScroll("mainContainer")],
  components: {
    Layout,
    BlogDetail,
    BlogTOC,
    BlogComment,
  },
  data() {
    return {
      newToc: [], // 若toc为空, 则会自行创建toc并存储在这
    };
  },
  created() {
    this.$bus.$on("blogDetailToc", this.setBlogDetailToc); // 监听设置toc的事件
  },
  destroyed() {
    // 组件销毁时候在事件总线中取消监听
    this.$bus.$off("blogDetailToc", this.setBlogDetailToc);
  },
  methods: {
    async fetchData() {
      // 请求的结果将会通过mixins混入, 数据data为请求结果中的data
      let resp = await getBlog(this.$route.params.id);
      // resp = null; // 模拟文章不存在的情况
      if (!resp) {
        // 如果文章不存在
        this.$router.push("/404"); // 跳转到404页面
        return;
      }
      titleController.setRouteTitle(resp.title);
      return resp;
    },
    // 设置toc
    setBlogDetailToc(toc) {
      // console.log("设置toc");
      this.newToc = toc;
    }
    // 因为已经在mixin/mainScroll.js里写好了, 所以以下部分就不需要了
    // handleScroll() {
    //   this.$bus.$emit("mainScroll", this.$refs.mainContainer);
    // },
    // handleSetMainScroll(scrollTop) {
    //   this.$refs.mainContainer.scrollTop = scrollTop;
    // },
  },
  // 因为已经在mixin/mainScroll.js里写好了, 所以以下部分就不需要了
  // mounted() {
  //   this.$bus.$on("setMainScroll", this.handleSetMainScroll);
  //   this.$refs.mainContainer.addEventListener("scroll", this.handleScroll);
  // },
  // beforeDestroy() { // 因为用destroyed的话mainContainer元素已经被销毁找不到了, 所以这里使用beforeDestroy
  //   this.$bus.$emit("mainScroll");
  //   // 组件销毁之后取消事件
  //   this.$refs.mainContainer.removeEventListener("scroll", this.handleScroll);
  //   this.$bus.$off("setMainScroll", this.handleSetMainScroll);
  // },
  updated() {
    // 当页面更新后重新设置hash值, [因为页面最开始没跳转到锚链接的位置[dom元素还未加载完成], 所以需要自己手动跳转]
    const hash = location.hash;
    location.hash = "";
    // 这里等待一段时间的原因是浏览器渲染需要一段时间, 如果直接修改就没有效果了
    setTimeout(() => {
      location.hash = hash; // 将hash改为原来的hash, 页面会因此定位到相应锚链接的位置
    }, 50);
  },
};
</script>

<style lang="less" scoped>
.main-container {
  overflow-y: scroll;
  height: 100%;
  box-sizing: border-box;
  padding: 20px;
  position: relative; // 因为loading效果需要依照它定位
  width: 100%;
  overflow-x: hidden;
  scroll-behavior: smooth; // 滚动条平滑滚动
  .title {
    padding-top: 20px;
    border-top: 2px solid #ccc;
    font-size: 28px;
    font-weight: bold;
    margin: 20px 0;
  }
}
.right-container {
  width: 300px;
  height: 100%;
  padding: 20px;
  overflow-y: scroll;
  box-sizing: border-box;
  position: relative;
}
</style>
